package com.web.utils;

import com.web.constant.DataPackageConstants;
import com.web.pojo.domain.Device;
import com.web.pojo.domain.DeviceGroup;
import com.web.pojo.dto.*;
import loracrypto.en_de_crypto.Cryptor;
import loramic.certify.MicCertifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: wws
 * @Date: 2021/1/9 0:21
 * describe:
 */

@Component
public class DownLinkDataUtil {


    static RedisUtil redisUtil;

    @Autowired
    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    public static byte[] DeviceGroupCommands(byte[] token, byte[] gatewayEui, byte[] payload) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(12 + payload.length);
        byteBuffer.put(DataPackageConstants.DEVICE_GROUP);
        byteBuffer.put(token);
        byteBuffer.put(DataPackageConstants.DOWN_LINK);
        byteBuffer.put(gatewayEui);
        byteBuffer.put(payload);
        return byteBuffer.array();
    }

    /**
     * 生成最终下行数据
     * @param token
     * @param freqType 频点偏移类型
     * @param deviceAddr 设备地址
     * @param payload 载荷
     * @return 下行数据
     */
    public static byte[] generateDownLinkData(byte[] token, byte freqType, byte[] deviceAddr, byte[] payload) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(9 + payload.length);
        byteBuffer.put(DataPackageConstants.DATA_DOWNLINK);
        byteBuffer.put(token);
        byteBuffer.put(DataPackageConstants.DOWN_LINK);
        byteBuffer.put(freqType);
        byteBuffer.put(deviceAddr);
        byteBuffer.put(payload);
        return byteBuffer.array();
    }

    /**
     * 生成PHYPayload
     * @param MACPayload MAC载荷
     * @param MIC 加密MIC
     * @return 结果
     */
    public static byte[] generatePHYPayload(byte[] MACPayload, byte[] MIC) {
        byte[] data = new byte[MACPayload.length + MIC.length];
        System.arraycopy(MACPayload, 0, data, 0, MACPayload.length);
        System.arraycopy(MIC, 0, data, MACPayload.length, MIC.length);
        return data;
    }

    /**
     * 生成设备操作命令数据
     * @param device 设备信息
     * @param FRMPayload 操作命令
     * @return 结果
     */
    public static byte[] generateDownPayload(Device device, byte[] FRMPayload) {
//        System.out.println("FRMPayload.length" + FRMPayload.length);
//        byte[] FHDR = generateFHDR(ToolUtil.toByteArray(device.getDeviceAddr()), DataPackageConstants.FCTRL, DataPackageConstants.getLoraFCnt());
        byte[] loraFCnt = redisUtil.getFhdrFCnt(device.getDeviceAddr());
        System.out.println("loraFCnt");
        show(loraFCnt);
        byte[] FHDR = generateFHDR(ToolUtil.toByteArray(device.getDeviceAddr()), DataPackageConstants.FCTRL, loraFCnt);

//        System.out.println("FHDR.length" + FHDR.length);
        byte[] MACPayload = generateMACPayload(DataPackageConstants.DEVICE_CONTROL_MHDR, FHDR, DataPackageConstants.FPORT, FRMPayload);
//        System.out.println("MACPayload.length" + MACPayload.length);

        byte[] downMsgEnCrypto = Cryptor.downMsgEnCrypto(MACPayload, ToolUtil.toByteArray(device.getDeviceAppskey()));
        System.out.println("downMsgEnCrypto.length" + downMsgEnCrypto.length);
        show(downMsgEnCrypto);
        show(MACPayload);
        System.arraycopy(downMsgEnCrypto, 0, MACPayload, MACPayload.length - downMsgEnCrypto.length, downMsgEnCrypto.length);
        byte[] MIC = MicCertifier.downMsgMicGenerate(MACPayload, ToolUtil.toByteArray(device.getDeviceNwkskey()), 4);
        byte[] PHYPayload = generatePHYPayload(MACPayload, MIC);
        System.out.println("PHYPayload.length" + PHYPayload.length);
        show(PHYPayload);
        return PHYPayload;
    }


    /**
     * 生成设备组操作命令数据(默认组)
     * @param FRMPayload 操作命令
     * @return 结果
     */
    public static byte[] generateGroupDownPayload(byte[] FRMPayload) {
//        System.out.println("FRMPayload.length" + FRMPayload.length);
        byte[] loraFCnt = redisUtil.getFRMPayloadFCnt(ToolUtil.printHexBinary(DataPackageConstants.DEFAULT_GROUP_ADDR));
        System.out.println("loraFCnt"+Arrays.toString(loraFCnt));

        byte[] FHDR = generateFHDR(DataPackageConstants.DEFAULT_GROUP_ADDR, DataPackageConstants.FCTRL, loraFCnt);
//        System.out.println("FHDR.length" + FHDR.length);
        byte[] MACPayload = generateMACPayload(DataPackageConstants.DEVICE_CONTROL_MHDR, FHDR, DataPackageConstants.MULTI_FPORT, FRMPayload);
//        System.out.println("MACPayload.length" + MACPayload.length);

        byte[] downMsgEnCrypto = Cryptor.downMsgEnCrypto(MACPayload, DataPackageConstants.DEFAULT_GROUP_APPSKEY);
        System.out.println("downMsgEnCrypto.length" + downMsgEnCrypto.length);
//        show(downMsgEnCrypto);
//        show(MACPayload);
        System.arraycopy(downMsgEnCrypto, 0, MACPayload, MACPayload.length - downMsgEnCrypto.length, downMsgEnCrypto.length);
        byte[] MIC = MicCertifier.downMsgMicGenerate(MACPayload,DataPackageConstants.DEFAULT_GROUP_NWKSKEY , 4);
        byte[] PHYPayload = generatePHYPayload(MACPayload, MIC);
//        System.out.println("PHYPayload.length" + PHYPayload.length);
//        show(PHYPayload);
        return PHYPayload;
    }

    /**
     * 生成设备组操作命令数据
     * @param deviceGroup 设备组信息
     * @param FRMPayload 操作命令
     * @return 结果
     */
    public static byte[] generateGroupDownPayload(DeviceGroup deviceGroup, byte[] FRMPayload) {
//        System.out.println("FRMPayload.length" + FRMPayload.length);
        byte[] loraFCnt = redisUtil.getFRMPayloadFCnt(ToolUtil.printHexBinary(DataPackageConstants.DEFAULT_GROUP_ADDR));
        System.out.println("loraFCnt"+Arrays.toString(loraFCnt));
        System.out.println(deviceGroup.getDeviceGroupAddr());
        byte[] FHDR = generateFHDR(ToolUtil.toByteArray(deviceGroup.getDeviceGroupAddr()), DataPackageConstants.FCTRL, loraFCnt);
//        System.out.println("FHDR.length" + FHDR.length);
        byte[] MACPayload = generateMACPayload(DataPackageConstants.DEVICE_CONTROL_MHDR, FHDR, DataPackageConstants.FPORT, FRMPayload);
//        System.out.println("MACPayload.length" + MACPayload.length);

        byte[] downMsgEnCrypto = Cryptor.downMsgEnCrypto(MACPayload, ToolUtil.toByteArray(deviceGroup.getDeviceGroupAppskey()));
        System.out.println("downMsgEnCrypto.length" + downMsgEnCrypto.length);
//        show(downMsgEnCrypto);
//        show(MACPayload);
        System.arraycopy(downMsgEnCrypto, 0, MACPayload, MACPayload.length - downMsgEnCrypto.length, downMsgEnCrypto.length);
        byte[] MIC = MicCertifier.downMsgMicGenerate(MACPayload, ToolUtil.toByteArray(deviceGroup.getDeviceGroupNwkskey()), 4);
        byte[] PHYPayload = generatePHYPayload(MACPayload, MIC);
//        System.out.println("PHYPayload.length" + PHYPayload.length);
//        show(PHYPayload);
        return PHYPayload;
    }


    public static void show(byte[] b) {
        for (int i = 0; i < b.length; i++) {
            System.out.printf("%02x ", b[i]);
        }
        System.out.println();
    }


    /**
     * 生成MAC载荷
     * @param FHDR
     * @param FPort
     * @param FRMPayload
     * @return
     */
    public static byte[] generateMACPayload(byte MHDR, byte[] FHDR, byte FPort, byte[] FRMPayload) {
        byte[] data = new byte[FHDR.length + 2 + FRMPayload.length];
        data[0] = MHDR;
        System.arraycopy(FHDR, 0, data, 1, FHDR.length);
        data[FHDR.length + 1] = FPort;
        System.arraycopy(FRMPayload, 0, data, FHDR.length + 2, FRMPayload.length);
        return data;
    }


    /**
     * 生成FHDR（有FOpts）
     * @param deviceAddr
     * @param FCtrl
     * @param FCnt
     * @param FOpts
     * @return
     */
    public static byte[] generateFHDR(byte[] deviceAddr, byte FCtrl, byte[] FCnt, byte[] FOpts) {
        byte[] b = new byte[deviceAddr.length + 1 + FCnt.length + FOpts.length];
        System.arraycopy(deviceAddr, 0, b, 0, deviceAddr.length);
        b[4] = FCtrl;
        System.arraycopy(FCnt, 0, b, 5, FCnt.length);
        System.arraycopy(FOpts, 0, b, 7, FOpts.length);
        return b;
    }


    /**
     * 生成FHDR（无FOpts）
     * @param deviceAddr 设备addr
     * @param FCtrl
     * @param FCnt
     * @return 结果
     */
    public static byte[] generateFHDR(byte[] deviceAddr, byte FCtrl, byte[] FCnt) {
        byte[] b = new byte[deviceAddr.length + 1 + FCnt.length];
        System.arraycopy(deviceAddr, 0, b, 0, deviceAddr.length);
        b[4] = FCtrl;
        System.arraycopy(FCnt, 0, b, 5, FCnt.length);
        return b;
    }

    /**
     * 生成设置开关状态的命令帧
     * @param deviceChannelParameter1 通道1命令
     * @param deviceChannelParameter2 通道2命令
     * @return 结果
     */
    public static byte[] switchStatePayLoad(byte[] FCnt, byte deviceChannelParameter1, byte deviceChannelParameter2) {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.SWITCH_LIGHT_STATUS);
        b.put(FCnt);
        b.put(DataPackageConstants.SWITCH_LIGHT_STATUS_SET);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(deviceChannelParameter1);
        b.put(deviceChannelParameter2);
        return b.array();
    }

    /**
     * 生成设置开关状态的命令帧
     * @return 结果
     */
    public static byte[] switchStatePayLoad(byte[] FCnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_LIGHT_STATUS);
        b.put(FCnt);
        b.put(DataPackageConstants.SWITCH_LIGHT_STATUS_GET);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        return b.array();
    }

    /**
     * 生成设置手动、远程、定时开关控制的命令帧
     * @param channel 通道
     * @param manual 手动
     * @param remotely 远程
     * @param timing 定时
     * @return
     */
    public static byte[] switchControlPayLoad(byte[] fcnt, byte channel, byte manual, byte remotely, byte timing) {
        ByteBuffer b = ByteBuffer.allocate(9);
        b.put(DataPackageConstants.SWITCH_CONTROL_STATUS);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_CONTROL_STATUS_SET);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(channel);
        b.put(manual);
        b.put(remotely);
        b.put(timing);
        return b.array();
    }

    /**
     * 生成获取手动、远程、定时开关控制的命令帧
     * @return 结果
     */
    public static byte[] switchControlPayLoad(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(9);
        b.put(DataPackageConstants.SWITCH_CONTROL_STATUS);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_CONTROL_STATUS_GET);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);

        return b.array();
    }

    /**
     * 生成设置手动、远程、定时开关控制的命令帧
     * @return 结果
     */
    public static byte[] switchControlPayLoad(byte[] fcnt, SetSwitchControlStateDTO dto) {
        ByteBuffer b = ByteBuffer.allocate(11);
        b.put(DataPackageConstants.SWITCH_CONTROL_STATUS);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_CONTROL_STATUS_SET);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(dto.getChannel1Manual());
        b.put(dto.getChannel1Remotely());
        b.put(dto.getChannel1Timing());
        b.put(dto.getChannel2Manual());
        b.put(dto.getChannel2Remotely());
        b.put(dto.getChannel2Timing());
        return b.array();
    }

    /**
     * 生成设置定时开关时间表
     * @param dto
     * @return
     */
    public static byte[] switchSchedulePayLoad(byte[] fcnt, SetSwitchScheduleDTO dto) {
        Integer i = dto.getSchedule().size() * 4;
        ByteBuffer b = ByteBuffer.allocate(6 + i);
        b.put(DataPackageConstants.SWITCH_SCHEDULE);
        b.put(fcnt);
        b.put((byte) (2 + i));
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(dto.getChannel());
        for (ScheduleDTO scheduleDTO : dto.getSchedule()) {
            b.put(scheduleDTO.getStartingTimeHour());
            b.put(scheduleDTO.getStartingTimeMinute());
            b.put(scheduleDTO.getOpenTimeTimeHour());
            b.put(scheduleDTO.getOpenTimeTimeMinute());
        }
        return b.array();
    }

    /**
     * 生成获取定时开关时间表
     * @param channel
     * @return
     */
    public static byte[] switchSchedulePayLoad(byte[] fcnt, byte channel) {
        ByteBuffer b = ByteBuffer.allocate(6);
        b.put(DataPackageConstants.SWITCH_SCHEDULE);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_SCHEDULE_GET);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        b.put(channel);
        return b.array();
    }

    /**
     * 设置开关调光等级
     * @param dto 参数
     * @return 结果
     */
    public static byte[] switchDimmingLevel(byte[] fcnt, SetSwitchDimmingLevelDTO dto) {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.SWITCH_DIMMING_LEVEL);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_DIMMING_LEVEL_SET);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(dto.getDeviceChannelParameter1());
        b.put(dto.getDeviceChannelParameter2());
        return b.array();
    }

    /**
     * 获取开关调光等级
     * @return 结果
     */
    public static byte[] switchDimmingLevel(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.SWITCH_DIMMING_LEVEL);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_DIMMING_LEVEL_SET);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        return b.array();
    }

    /**
     * 获取开关的温度、湿度、露点、电源/电量、设备状态
     * @return 结果
     */
    public static byte[] getSwitchDeviceStatus(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_DEVICE_ATTRIBUTES);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_DEVICE_ATTRIBUTES_GET);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        return b.array();
    }

    /**
     * 设置上报周期
     * @return 结果
     */
    public static byte[] switchReportingPeriod(byte[] fcnt, SetSwitchReportingPeriodDTO dto) {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.SWITCH_REPORTING_PERIOD);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_REPORTING_PERIOD_SET);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(dto.getReportHour());
        b.put(dto.getReportMinute());
        return b.array();
    }

    /**
     * 获得上报周期
     * @return 结果
     */
    public static byte[] switchReportingPeriod(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.SWITCH_REPORTING_PERIOD);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_REPORTING_PERIOD_GET);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        return b.array();
    }

    /**
     * 获取开关工作时间
     * @return 结果
     */
    public static byte[] getOperatingHours(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_OPERATING_HOURS);
        b.put(fcnt);
        b.put(DataPackageConstants.OPERATING_HOURS_GET);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        return b.array();
    }

    /**
     * 设置设备APPKEY
     * @return 结果
     */
    public static byte[] setAppKey(byte[] fcnt, SetSwitchAppKeyDTO dto) {
        ByteBuffer b = ByteBuffer.allocate(21);
        b.put(DataPackageConstants.SWITCH_APPKEY);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_APPKEY_SET);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(ToolUtil.toByteArray(dto.getAppkey()));
        return b.array();
    }

    /**
     * 获取设备类型
     * @return 结果
     */
    public static byte[] getDeviceType(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_GET_INFO);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_APPKEY_GET);
        b.put(DataPackageConstants.SWITCH_GET_INFO_GET);
        return b.array();
    }

    /**
     * 往设备组中添加设备
     * @return 结果
     */
    public static byte[] deviceGroupAddDevice(byte[] appkey, byte[] addr, byte[] deviceEui) {
        ByteBuffer b = ByteBuffer.allocate(31);
        b.put(DataPackageConstants.GROUP_ADD_SWITCH);
        b.put((byte) 29);
        b.put(appkey);
        b.put(addr);
        b.put(deviceEui);
        return b.array();
    }

    /**
     * 往设备组中添加设备
     * @return 结果
     */
    public static byte[] deviceGroupAddDevice(byte[] appkey, byte[] addr, List<Device> deviceList) {
        int i = deviceList.size() * 8;
        ByteBuffer b = ByteBuffer.allocate(22 + i);
        b.put(DataPackageConstants.GROUP_ADD_SWITCH);
        b.put((byte) 29);
        b.put(appkey);
        b.put(addr);
        for (Device device : deviceList) {
            b.put(ToolUtil.toByteArray(device.getDeviceEui()));
        }
        return b.array();
    }


    /**
     * 删除一个终端所有分组
     * @return 结果
     */
    public static byte[] deleteDeviceGroup(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_DELETE_GROUP);
        b.put(fcnt);
        b.put((byte) 0x01);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        return b.array();
    }

    /**
     * 获取一个终端所有分组
     * @return 结果
     */
    public static byte[] selectDeviceGroup(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_SET_GROUP);
        b.put(fcnt);
        b.put((byte) 0x01);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        return b.array();
    }

    /**
     * 终端重启
     * @return 结果
     */
    public static byte[] deviceReboot(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_DELETE_REBOOT);
        b.put(fcnt);
        b.put((byte) 0x01);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        return b.array();
    }

    /**
     * 恢复终端默认设置
     * @return 结果
     */
    public static byte[] deviceReset(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_DELETE_RESET);
        b.put(fcnt);
        b.put((byte) 0x01);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        return b.array();
    }

    /**
     * 设置设备时间
     * @return 结果
     */
    public static byte[] setDeviceTime(byte[] fcnt,byte day, byte month, byte year, byte second, byte minute, byte hour) {
        ByteBuffer b = ByteBuffer.allocate(11);
        b.put(DataPackageConstants.SWITCH_DELETE_TIME);
        b.put(fcnt);
        b.put((byte) 0x07);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(day);
        b.put(month);
        b.put(year);
        b.put(second);
        b.put(minute);
        b.put(hour);
        return b.array();
    }
    /**
     * 获得设备时间
     * @return 结果
     */
    public static byte[] getDeviceTime(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.SWITCH_DELETE_TIME);
        b.put(fcnt);
        b.put((byte) 0x01);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        return b.array();
    }


    /**
     * 设置设备组开关状态
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchStatePayLoad(byte deviceChannelParameter1, byte deviceChannelParameter2) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.GROUP_SWITCH_LIGHT_STATUS);
        b.put((byte) 03);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(deviceChannelParameter1);
        b.put(deviceChannelParameter2);
        return b.array();
    }

    /**
     * 设置设备组开关控制状态
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchControlStatePayLoad(SetSwitchControlStateDTO dto) {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.GROUP_SWITCH_CONTROL_STATUS_STATUS);
        b.put((byte) 06);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(dto.getChannel1Manual());
        b.put(dto.getChannel1Remotely());
        b.put(dto.getChannel1Timing());
        b.put(dto.getChannel2Manual());
        b.put(dto.getChannel2Remotely());
        b.put(dto.getChannel2Timing());
        return b.array();
    }

    /**
     * 设置设备组开关时间表
     * @return 结果
     */
    public static byte[] deviceGroupSwitchControlSchedulePayLoad( SetSwitchScheduleDTO dto) {
        Integer i = dto.getSchedule().size() * 4;
        ByteBuffer b = ByteBuffer.allocate(4+i);
        b.put(DataPackageConstants.GROUP_SWITCH_SCHEDULE);
        b.put((byte) (2+i));
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(dto.getChannel());
        for (ScheduleDTO scheduleDTO : dto.getSchedule()) {
            b.put(scheduleDTO.getStartingTimeHour());
            b.put(scheduleDTO.getStartingTimeMinute());
            b.put(scheduleDTO.getOpenTimeTimeHour());
            b.put(scheduleDTO.getOpenTimeTimeMinute());
        }
        return b.array();
    }

    /**
     * 设置设备组调关等级
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchDimmingLevelPayLoad(byte deviceChannelParameter1, byte deviceChannelParameter2) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.GROUP_SWITCH_DIMMING_LEVEL);
        b.put((byte) 0x03);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(deviceChannelParameter1);
        b.put(deviceChannelParameter2);
        return b.array();
    }

    /**
     * 设置设备组上报周期
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchReportingPeriod(byte reportHour, byte reportMinute) {
        ByteBuffer b = ByteBuffer.allocate(5);
        b.put(DataPackageConstants.GROUP_SWITCH_REPORTING_PERIOD);
        b.put((byte) 0x03);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(reportHour);
        b.put(reportMinute);
        return b.array();
    }

    /**
     * 设置设备组APPKEY
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchAppKey(byte[] appkey) {
        ByteBuffer b = ByteBuffer.allocate(19);
        b.put(DataPackageConstants.GROUP_SWITCH_APPKEY);
        b.put((byte) 0x11);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(appkey);
        return b.array();
    }

    /**
     * 组重启
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchReboot() {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.GROUP_SWITCH_REBOOT);
        b.put((byte) 0x01);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        return b.array();
    }

    /**
     * 组恢复默认设置
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchReset() {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.GROUP_SWITCH_RESET);
        b.put((byte) 0x01);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        return b.array();
    }

    /**
     * 组设置设备时间
     * @return 结果
     */
    public static byte[] setDeviceGroupSwitchTime(byte day, byte month, byte year, byte second, byte minute, byte hour) {
        ByteBuffer b = ByteBuffer.allocate(7);
        b.put(DataPackageConstants.GROUP_SWITCH_TIME);
        b.put((byte) 0x07);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(day);
        b.put(month);
        b.put(year);
        b.put(second);
        b.put(minute);
        b.put(hour);
        return b.array();
    }

    /**
     * 给设备分配设备组
     * @return 结果
     */
    public static byte[] setDeviceGroupByDevice(byte[] fcnt, String appkey, String addr) {
        ByteBuffer b = ByteBuffer.allocate(25);
        b.put(DataPackageConstants.SWITCH_SET_GROUP);
        b.put(fcnt);
        b.put((byte) 21);
        b.put(DataPackageConstants.SWITCH_OPERATING_SET);
        b.put(ToolUtil.toByteArray(appkey));
        b.put(ToolUtil.toByteArray(addr));
        return b.array();
    }

    /**
     * 获取设备类型、初始化上行通道、版本号
     * @return 结果
     */
    public static byte[] setAppKey(byte[] fcnt) {
        ByteBuffer b = ByteBuffer.allocate(21);
        b.put(DataPackageConstants.SWITCH_APPKEY);
        b.put(fcnt);
        b.put(DataPackageConstants.SWITCH_APPKEY_GET);
        b.put(DataPackageConstants.SWITCH_OPERATING_GET);
        return b.array();
    }

    /**
     * 生成发给网关注册或删除终端设备的命令
     * @param token 两位随机数
     * @param type 注册或删除 （0x01 注册 ，0x02删除)
     * @param deviceEui 设备唯一标识符
     * @return 下行数据
     */
    public static byte[] deviceRegister(byte[] token, byte type, byte[] deviceEui, byte[] addr) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(17);
        byteBuffer.put(DataPackageConstants.DEVICE_REGISTERED_OR_DELETE);
        byteBuffer.put(token);
        byteBuffer.put(DataPackageConstants.DOWN_LINK);
        byteBuffer.put(type);
        byteBuffer.put(deviceEui);
        byteBuffer.put(addr);
        return byteBuffer.array();
    }

    /**
     * 生成发给网关注册或删除网关设备的命令
     * @param token 两位随机数
     * @param type 注册或删除 （0x01 注册 ，0x02删除)
     * @param gateWayEui 设备唯一标识符
     * @return 下行数据
     */
    public static byte[] gatewayRegister(byte[] token, byte type, byte[] gateWayEui) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(13);
        byteBuffer.put(DataPackageConstants.GATEWAY_REGISTERED_OR_DELETE);
        byteBuffer.put(token);
        byteBuffer.put(DataPackageConstants.DOWN_LINK);
        byteBuffer.put(type);
        byteBuffer.put(gateWayEui);
        return byteBuffer.array();
    }

}
